import Compiler from './compiler'
import { querySelector } from './dom'
import { forEach, mergeOptions } from './utils'
import { createVnode, patch } from './vnode'

const { observe, LifeCircle, Event, Watcher } = require('./reactive')

class Vue {
  constructor(options) {
    this.$options = options
    // 合并选项
    const merOps = mergeOptions(options, options)
    // 初始化数据 provide，lifecircle，event，props
    this._initDate(merOps)
    // 响应式
    observe(this.data)
    // 收集依赖
  }
  $mount(sel) {
    const container = querySelector(sel)
    const { template } = this.$options
    const compiler = new Compiler()
    // 编译模板 -> ast
    const ast = compiler.parse(template)
    // ast -> vnode
    let oldVnode = null
    let updateComponent = () => {
      const vnode = createVnode(this, ast)
      console.log(vnode)
      patch(container, vnode, oldVnode)
      oldVnode = vnode
    }
    // vnode -> patch
    this.watcher = new Watcher(updateComponent, null)
  }
  $nextTick(fn) {}
  $emit(name, payload) {}
  inject(key) {
    return this.inject?.[key]
  }
  _initDate(merOps) {
    const { parent = {} } = merOps
    this.$parent = parent
    // provide -> inject
    this.inject = parent.provide || {}
    // lifeCircle
    this.lifeCircle = new LifeCircle()
    this.lifeCircle.init(merOps)
    // event
    this.event = new Event()
    this.event.init(merOps)
    // props
    forEach(merOps.props, (val, key) => {
      this.props[key] = val
    })
    // data
    this.data = merOps.data
  }
}

export default Vue
